package edu.scau.mis.system.security.config;

import edu.scau.mis.system.security.filter.MisAuthenticationTokenFilter;
import edu.scau.mis.system.security.handler.AuthenticationEntryPointImpl;
import edu.scau.mis.system.security.handler.LogoutSuccessHandlerImpl;
import edu.scau.mis.system.security.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration {

    /* 不受控静态资源RUL */
    private static final String[] SECURITY_IGNORE_RESOURCE_URL = {
            "/doc.html",                   // Knife4j 文档页
            "/webjars/**",                 // Knife4j 依赖的 JS/CSS
            "/swagger-resources/**",       // Swagger 资源
            "/v3/api-docs/**",             // OpenAPI 规范
            "/favicon.ico",                // 网站图标
            "/druid/**"                    // Druid 监控
    };

    /* 不受控API_PATH */
    private static final String[] SECURITY_IGNORE_API_PATH = {
            "/auth/**",  // 添加开头的 /
            "/login",
            "/login/**",
            "/druid/**",
            "/category/**",
            "/product/**",
            "/sale/**",
            "/role/**",
            "/user/**",
            "/menu/**",
            "/api/**",
           "/log/**",
            "/api/**",
            "/promotion/**",
            "/upload"
    };

    private final UserDetailsServiceImpl userDetailsService;

    @Autowired
    public SecurityConfiguration(UserDetailsServiceImpl userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Autowired
    private AuthenticationEntryPointImpl unauthorizedHandler;

    @Autowired
    private LogoutSuccessHandlerImpl logoutSuccessHandler;

    @Autowired
    private MisAuthenticationTokenFilter misAuthenticationTokenFilter;

    /* 配置 SecurityFilterChain */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        /* 解决跨域 */
        http.cors((cors -> cors.configure(http)));

        /* 禁用跨站请求伪造csrf */
        http.csrf(csrf -> csrf.disable());

        /* 配置会话管理为无状态（适合JWT） */
        http.sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        );

        http.authorizeHttpRequests(authorize -> authorize
                .requestMatchers(
                        SECURITY_IGNORE_RESOURCE_URL // 放行静态资源路径
                ).permitAll()
                .requestMatchers(SECURITY_IGNORE_API_PATH).permitAll() // 允许公共路径

                .anyRequest().authenticated() // 其他请求需要认证
        );
        /* 配置token验证过滤器 */
        http.addFilterBefore(misAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        /* 配置认证失败处理 */
        http.exceptionHandling(exception -> exception
                .authenticationEntryPoint(unauthorizedHandler)
        );

        /* 配置退出 */
        http.logout(logout -> logout
                .logoutUrl("/logout")
                .logoutSuccessHandler(logoutSuccessHandler)
        );



        return http.build();
    }

    /* 配置密码加密 */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /* 配置认证管理器 */
    @Bean
    public AuthenticationManager authenticationManager(BCryptPasswordEncoder passwordEncoder) {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService); // 设置 UserDetailsService
        provider.setPasswordEncoder(passwordEncoder);       // 设置密码编码器
        return new ProviderManager(provider);
    }



}